home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / util / moni / Scout-src.lha / source / objects / scout_classes.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-09-17  |  15.1 KB  |  421 lines

  1. /**
  2.  * Scout - The Amiga System Monitor
  3.  *
  4.  *------------------------------------------------------------------
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * You must not use this source code to gain profit of any kind!
  21.  *
  22.  *------------------------------------------------------------------
  23.  *
  24.  * @author Andreas Gelhausen
  25.  * @author Richard Körber <rkoerber@gmx.de>
  26.  */
  27.  
  28. #include "system_headers.h"
  29.  
  30. struct ClassesCallbackUserData {
  31.     APTR ud_Tree;
  32.     ULONG ud_Count;
  33. };
  34.  
  35. static __asm __saveds LONG classtree_confunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_ConstructMessage *msg, register __a0 struct Hook *hook)
  36. {
  37.     return AllocListEntry(msg->MemPool, msg->UserData, sizeof(struct ClassEntry));
  38. }
  39.  
  40. MakeHook(classtree_conhook, classtree_confunc);
  41.  
  42. static __asm __saveds LONG classtree_desfunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_ConstructMessage *msg, register __a0 struct Hook *hook)
  43. {
  44.     FreeListEntry(msg->MemPool, &msg->UserData);
  45.  
  46.     return 0;
  47. }
  48.  
  49. MakeHook(classtree_deshook, classtree_desfunc);
  50.  
  51. static __asm __saveds LONG classtree_dspfunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_DisplayMessage *msg, register __a0 struct Hook *hook)
  52. {
  53.     if (msg->TreeNode != NULL) {
  54.         struct ClassEntry *ce = msg->TreeNode->tn_User;
  55.  
  56.         msg->Array[0] = ce->ce_Address;
  57.         msg->Array[1] = ce->ce_ClassName;
  58.         msg->Array[2] = ce->ce_ObjectCount;
  59.         msg->Array[3] = ce->ce_SubClassCount;
  60.         msg->Array[4] = ce->ce_Dispatcher;
  61.     } else {
  62.         msg->Array[0] = "Address";
  63.         msg->Array[1] = "cl_ID";
  64.         msg->Array[2] = "Objects";
  65.         msg->Array[3] = "Subclasses";
  66.         msg->Array[4] = "cl_Dispatcher";
  67.         msg->Preparse[0] = MUIX_B;
  68.         msg->Preparse[1] = MUIX_B;
  69.         msg->Preparse[2] = MUIX_B;
  70.         msg->Preparse[3] = MUIX_B;
  71.         msg->Preparse[4] = MUIX_B;
  72.     }
  73.  
  74.     return 0;
  75. }
  76.  
  77. MakeHook(classtree_dsphook, classtree_dspfunc);
  78.  
  79. static __asm __saveds LONG classtree_cmpfunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_CompareMessage *msg, register __a0 struct Hook *hook)
  80. {
  81.     struct ClassEntry *ce1, *ce2;
  82.     LONG cmp;
  83.  
  84.     ce1 = (struct ClassEntry *)msg->TreeNode1->tn_User;
  85.     ce2 = (struct ClassEntry *)msg->TreeNode2->tn_User;
  86.  
  87.     cmp = stricmp(ce1->ce_SuperClassName, ce2->ce_SuperClassName);
  88.     if (cmp == 0) cmp = stricmp(ce1->ce_ClassName, ce2->ce_ClassName);
  89.  
  90.     return cmp;
  91. }
  92.  
  93. MakeHook(classtree_cmphook, classtree_cmpfunc);
  94.  
  95. static __asm __saveds LONG classtree_findfunc(register __a2 Object *obj, register __a1 struct MUIP_NListtree_FindUserDataMessage *msg, register __a0 struct Hook *hook)
  96. {
  97.     struct ClassEntry *ce;
  98.  
  99.     ce = (struct ClassEntry *)msg->UserData;
  100.  
  101.     if (ce) {
  102.         return stricmp((UBYTE *)msg->User, ce->ce_Address);
  103.     } else {
  104.         return ~0;
  105.     }
  106. }
  107.  
  108. MakeHook(classtree_findhook, classtree_findfunc);
  109.  
  110. static void ReceiveList( void (* callback)( struct ClassEntry *ce, void *userData ),
  111.                          void *userData )
  112. {
  113.     if (SendDaemon("GetClassList")) {
  114.         struct ClassEntry ce;
  115.  
  116.         while (ReceiveDecodedEntry((UBYTE *)&ce, sizeof(struct ClassEntry))) {
  117.             callback(&ce, userData);
  118.         }
  119.     }
  120. }
  121.  
  122. static void IterateList( void (* callback)( struct ClassEntry *ce, void *userData ),
  123.                          void *userData )
  124. {
  125.     struct IClass *myclass;
  126.  
  127.     if (myclass = MakeClass("« Scout Dummy Class »", "rootclass", NULL, 0, 0)) {
  128.         struct List *clist;
  129.         struct IClass *cl;
  130.         struct MinList tmplist;
  131.         struct ClassEntry *ce, *_ce;
  132.  
  133.         NewList((struct List *)&tmplist);
  134.  
  135.         AddClass(myclass);
  136.  
  137.         Forbid();
  138.  
  139.         clist = FindListOfNode((struct Node *)&myclass->cl_Dispatcher.h_MinNode);
  140.         ITERATE_LIST_REVERSE(clist, struct IClass *, cl) {
  141.             // iterate the list in reverse order, because we need rootclass to be inserted as the very first element
  142.             if (cl != myclass) {
  143.                 if (ce = AllocVec(sizeof(struct ClassEntry), MEMF_PUBLIC)) {
  144.                     struct Hook *disp;
  145.                     APTR dispentry;
  146.  
  147.                     disp = &cl->cl_Dispatcher;
  148.  
  149.                     ce->ce_Addr = cl;
  150.                     _snprintf(ce->ce_Address, sizeof(ce->ce_Address), "$%08lx", cl);
  151.                     if (cl->cl_Super) {
  152.                         stccpy(ce->ce_SuperClassName, cl->cl_Super->cl_ID, sizeof(ce->ce_SuperClassName));
  153.                     } else {
  154.                         stccpy(ce->ce_SuperClassName, nonetest(NULL), sizeof(ce->ce_SuperClassName));
  155.                     }
  156.                     _snprintf(ce->ce_SuperClassAddress, sizeof(ce->ce_SuperClassAddress), "$%08lx", cl->cl_Super);
  157.  
  158.                     dispentry = (disp->h_SubEntry) ? (APTR)disp->h_SubEntry : (APTR)disp->h_Entry;
  159.                     if (points2ram(dispentry)) {
  160.                         _snprintf(ce->ce_Dispatcher, sizeof(ce->ce_Dispatcher), MUIX_PH "$%08lx" MUIX_PT, dispentry);
  161.                     } else {
  162.                         _snprintf(ce->ce_Dispatcher, sizeof(ce->ce_Dispatcher), "$%08lx", dispentry);
  163.                     }
  164.  
  165.                     stccpy(ce->ce_ClassName, cl->cl_ID, sizeof(ce->ce_ClassName));
  166.                     _snprintf(ce->ce_ObjectCount, sizeof(ce->ce_ObjectCount), "%6lD", cl->cl_ObjectCount);
  167.                     _snprintf(ce->ce_SubClassCount, sizeof(ce->ce_SubClassCount), "%6lD", cl->cl_SubclassCount);
  168.  
  169.                     AddTail((struct List *)&tmplist, (struct Node *)ce);
  170.                 }
  171.             }
  172.         }
  173.  
  174.         Permit();
  175.  
  176.         ITERATE_CHANGING_LIST(&tmplist, struct ClassEntry *, ce, _ce) {
  177.             callback(ce, userData);
  178.             FreeVec(ce);
  179.         }
  180.  
  181.         FreeClass(myclass);
  182.     }
  183. }
  184.  
  185. static void UpdateCallback( struct ClassEntry *ce,
  186.                             void *userData )
  187. {
  188.     struct ClassesCallbackUserData *ud = (struct ClassesCallbackUserData *)userData;
  189.     struct MUI_NListtree_TreeNode *parent;
  190.     ULONG flags;
  191.     LONG subclasses;
  192.  
  193.     IsDec(ce->ce_SubClassCount, &subclasses);
  194.  
  195.     flags = 0;
  196.     if (subclasses > 0) flags = TNF_LIST | TNF_OPEN;
  197.  
  198.     parent = (struct MUI_NListtree_TreeNode *)DoMethod(ud->ud_Tree, MUIM_NListtree_FindUserData, MUIV_NListtree_FindUserData_ListNode_Root, ce->ce_SuperClassAddress, MUIV_NListtree_FindUserData_Flag_StartNode);
  199.     DoMethod(ud->ud_Tree, MUIM_NListtree_Insert, ce->ce_ClassName, ce, parent, MUIV_NListtree_Insert_PrevNode_Sorted, flags);
  200.     ud->ud_Count++;
  201. }
  202.  
  203. static void PrintCallback( struct ClassEntry *ce,
  204.                            void *userData )
  205. {
  206.     if (strncmp(ce->ce_Dispatcher, MUIX_PH, strlen(MUIX_PH)) == 0) {
  207.         PrintFOneLine((BPTR)userData, " %s %7s %11s  %-20s   %-9.9s   %-20s\n", ce->ce_Address, ce->ce_ObjectCount, ce->ce_SubClassCount, ce->ce_SuperClassName, ce->ce_Dispatcher + 2, ce->ce_ClassName);
  208.     } else {
  209.         PrintFOneLine((BPTR)userData, " %s %7s %11s  %-20s   %-9.9s   %-20s\n", ce->ce_Address, ce->ce_ObjectCount, ce->ce_SubClassCount, ce->ce_SuperClassName, ce->ce_Dispatcher, ce->ce_ClassName);
  210.     }
  211. }
  212.  
  213. static void SendCallback( struct ClassEntry *ce,
  214.                           void *userData )
  215. {
  216.     SendEncodedEntry((UBYTE *)ce, sizeof(struct ClassEntry));
  217. }
  218.  
  219. static ULONG __saveds mNew( struct IClass *cl,
  220.                             Object *obj,
  221.                             struct opSet *msg )
  222. {
  223.     APTR classlist, classtree, classtext, classcount, updateButton, printButton, removeButton, moreButton, exitButton;
  224.  
  225.     if (obj = (Object *)DoSuperNew(cl, obj,
  226.         MUIA_HelpNode, ClassesText,
  227.         MUIA_Window_ID, MakeID('C','L','A','S'),
  228.         WindowContents, VGroup,
  229.  
  230.             Child, classlist = MyNListtreeObject(&classtree, "BAR,BAR,BAR P=" MUIX_R ",BAR P=" MUIX_R ",BAR", &classtree_conhook, &classtree_deshook, &classtree_dsphook, &classtree_cmphook, &classtree_findhook, 1),
  231.             Child, MyBelowListview(&classtext, &classcount),
  232.  
  233.             Child, MyVSpace(4),
  234.  
  235.             Child, HGroup, MUIA_Group_SameSize, TRUE,
  236.                 Child, updateButton = MakeButton(txtUpdate),
  237.                 Child, printButton  = MakeButton(txtPrint),
  238.                 Child, removeButton = MakeButton(txtRemove),
  239.                 Child, moreButton   = MakeButton(txtMore),
  240.                 Child, exitButton   = MakeButton(txtExit),
  241.             End,
  242.         End,
  243.         TAG_MORE, msg->ops_AttrList))
  244.     {
  245.         struct ClassesWinData *cwd = INST_DATA(cl, obj);
  246.         APTR parent;
  247.  
  248.         cwd->cwd_ClassTree = classtree;
  249.         cwd->cwd_ClassText = classtext;
  250.         cwd->cwd_ClassCount = classcount;
  251.         cwd->cwd_RemoveButton = removeButton;
  252.         cwd->cwd_MoreButton = moreButton;
  253.  
  254.         parent = (APTR)GetTagData(MUIA_Window_ParentWindow, (ULONG)NULL, msg->ops_AttrList);
  255.  
  256.         set(obj, MUIA_Window_Title, MyGetWindowTitle("CLASSES", cwd->cwd_Title, sizeof(cwd->cwd_Title)));
  257.         set(obj, MUIA_Window_ActiveObject, classlist);
  258.         set(removeButton, MUIA_Disabled, TRUE);
  259.         set(moreButton, MUIA_Disabled, TRUE);
  260.  
  261.         DoMethod(parent,       MUIM_Window_AddChildWindow, obj);
  262.         DoMethod(obj,          MUIM_Notify, MUIA_Window_CloseRequest,   TRUE,           MUIV_Notify_Application, 5, MUIM_Application_PushMethod, parent, 2, MUIM_Window_RemChildWindow, obj);
  263.         DoMethod(classtree,    MUIM_Notify, MUIA_NListtree_Active,      MUIV_EveryTime, obj,                     1, MUIM_ClassesWin_ListChange);
  264.         DoMethod(classtree,    MUIM_Notify, MUIA_NListtree_DoubleClick, MUIV_EveryTime, obj,                     1, MUIM_ClassesWin_More);
  265.         DoMethod(updateButton, MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     1, MUIM_ClassesWin_Update);
  266.         DoMethod(printButton,  MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     1, MUIM_ClassesWin_Print);
  267.         DoMethod(removeButton, MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     1, MUIM_ClassesWin_Remove);
  268.         DoMethod(moreButton,   MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     1, MUIM_ClassesWin_More);
  269.         DoMethod(exitButton,   MUIM_Notify, MUIA_Pressed,               FALSE,          obj,                     3, MUIM_Set, MUIA_Window_CloseRequest, TRUE);
  270.     }
  271.  
  272.     return (ULONG)obj;
  273. }
  274.  
  275. static ULONG __saveds mDispose( struct IClass *cl,
  276.                                 Object *obj,
  277.                                 struct opSet *msg )
  278. {
  279.     struct ClassesWinData *cwd = INST_DATA(cl, obj);
  280.  
  281.     set(obj, MUIA_Window_Open, FALSE);
  282.     DoMethod(cwd->cwd_ClassTree, MUIM_NListtree_Clear, NULL, 0);
  283.  
  284.     return (DoSuperMethodA(cl, obj, msg));
  285. }
  286.  
  287. static ULONG __saveds mUpdate( struct IClass *cl,
  288.                                Object *obj,
  289.                                Msg msg )
  290. {
  291.     struct ClassesWinData *cwd = INST_DATA(cl, obj);
  292.     struct ClassesCallbackUserData ud;
  293.  
  294.     ApplicationSleep(TRUE);
  295.     set(cwd->cwd_ClassTree, MUIA_NListtree_Quiet, TRUE);
  296.     DoMethod(cwd->cwd_ClassTree, MUIM_NListtree_Clear, NULL, 0);
  297.  
  298.     ud.ud_Tree = cwd->cwd_ClassTree;
  299.     ud.ud_Count = 0;
  300.  
  301.     if (clientstate) {
  302.         ReceiveList(UpdateCallback, &ud);
  303.     } else {
  304.         IterateList(UpdateCallback, &ud);
  305.     }
  306.  
  307.     SetCountText(cwd->cwd_ClassCount, ud.ud_Count);
  308.     MySetContents(cwd->cwd_ClassText, "");
  309.  
  310.     set(cwd->cwd_ClassTree, MUIA_NListtree_Quiet, FALSE);
  311.     set(cwd->cwd_ClassTree, MUIA_NListtree_Active, MUIV_NListtree_Active_Off);
  312.     set(cwd->cwd_RemoveButton, MUIA_Disabled, TRUE);
  313.     set(cwd->cwd_MoreButton, MUIA_Disabled, TRUE);
  314.     ApplicationSleep(FALSE);
  315.  
  316.     return 0;
  317. }
  318.  
  319. static ULONG __saveds mPrint( struct IClass *cl,
  320.                               Object *obj,
  321.                               Msg msg )
  322. {
  323.     PrintClass(NULL);
  324.  
  325.     return 0;
  326. }
  327.  
  328. static ULONG __saveds mRemove( struct IClass *cl,
  329.                                Object *obj,
  330.                                Msg msg )
  331. {
  332.     struct ClassesWinData *cwd = INST_DATA(cl, obj);
  333.     struct MUI_NListtree_TreeNode *tn;
  334.  
  335.     if (tn = GetActiveTreeNode(cwd->cwd_ClassTree)) {
  336.         struct ClassEntry *ce = (struct ClassEntry *)tn->tn_User;
  337.  
  338.         if (MyRequest(msgYesNo, msgWantToRemoveClass, ce->ce_ClassName)) {
  339.             MyDoCommand("RemoveClass %s", ce->ce_Address);
  340.             DoMethod(obj, MUIM_ClassesWin_Update);
  341.         }
  342.     }
  343.  
  344.     return 0;
  345. }
  346.  
  347. static ULONG __saveds mMore( struct IClass *cl,
  348.                              Object *obj,
  349.                              Msg msg )
  350. {
  351.     struct ClassesWinData *cwd = INST_DATA(cl, obj);
  352.     struct MUI_NListtree_TreeNode *tn;
  353.  
  354.     if (tn = GetActiveTreeNode(cwd->cwd_ClassTree)) {
  355.         struct ClassEntry *ce = (struct ClassEntry *)tn->tn_User;
  356.         APTR detailWin;
  357.  
  358.         if (detailWin = ClassesDetailWindowObject,
  359.                 MUIA_Window_ParentWindow, obj,
  360.             End) {
  361.             set(detailWin, MUIA_ClassesDetailWin_Class, ce);
  362.             set(detailWin, MUIA_Window_Open, TRUE);
  363.         }
  364.     }
  365.  
  366.     return 0;
  367. }
  368.  
  369. static ULONG __saveds mListChange( struct IClass *cl,
  370.                                    Object *obj,
  371.                                    Msg msg )
  372. {
  373.     struct ClassesWinData *cwd = INST_DATA(cl, obj);
  374.     struct MUI_NListtree_TreeNode *tn;
  375.  
  376.     if (tn = GetActiveTreeNode(cwd->cwd_ClassTree)) {
  377.         struct ClassEntry *ce = (struct ClassEntry *)tn->tn_User;
  378.  
  379.         MySetContents(cwd->cwd_ClassText, "%s \"%s\"", ce->ce_Address, ce->ce_ClassName);
  380.         set(cwd->cwd_RemoveButton, MUIA_Disabled, FALSE);
  381.         if (!clientstate) set(cwd->cwd_MoreButton, MUIA_Disabled, FALSE);
  382.     }
  383.  
  384.     return 0;
  385. }
  386.  
  387. ULONG __asm __saveds ClassesWinDispatcher( register __a0 struct IClass *cl,
  388.                                            register __a2 Object *obj,
  389.                                            register __a1 Msg msg )
  390. {
  391.     switch (msg->MethodID) {
  392.         case OM_NEW:                     return (mNew(cl, obj, (APTR)msg));
  393.         case OM_DISPOSE:                 return (mDispose(cl, obj, (APTR)msg));
  394.         case MUIM_ClassesWin_Update:     return (mUpdate(cl, obj, (APTR)msg));
  395.         case MUIM_ClassesWin_Print:      return (mPrint(cl, obj, (APTR)msg));
  396.         case MUIM_ClassesWin_Remove:     return (mRemove(cl, obj, (APTR)msg));
  397.         case MUIM_ClassesWin_More:       return (mMore(cl, obj, (APTR)msg));
  398.         case MUIM_ClassesWin_ListChange: return (mListChange(cl, obj, (APTR)msg));
  399.     }
  400.  
  401.     return (DoSuperMethodA(cl, obj, msg));
  402. }
  403.  
  404. void PrintClass( char *filename )
  405. {
  406.     BPTR handle;
  407.  
  408.     if (handle = HandlePrintStart(filename)) {
  409.         PrintFOneLine(handle, "\n  Address  Objects  Subclasses  Superclass             Dispatcher  Name\n\n");
  410.         IterateList(PrintCallback, (void *)handle);
  411.     }
  412.  
  413.     HandlePrintStop();
  414. }
  415.  
  416. void SendClassList( void )
  417. {
  418.     IterateList(SendCallback, NULL);
  419. }
  420.  
  421.